#pragma once

#include <map>
#include "sys/IInterface.h"

enum {ERROR_ID = 0u};

template<typename T>
class FreeIdentifier
{
public:
	typedef std::map<uint32,T> CommandMap;

	FreeIdentifier(uint32 firstid,uint32 lastid,CommandMap& map)
		:m_mapCommands(map)
	{
		m_firstid = firstid;
		m_lastid = lastid;
	}
	uint32 GetUnique(const T& control)
	{
		uint32 nGlobalID = FindRegisteredGlobalCommandID(control);
		if (nGlobalID == ERROR_ID)
			nGlobalID = FindFreeCommandID();
		if (nGlobalID == ERROR_ID)
			return ERROR_ID;
		return nGlobalID;
	}

private:
	void operator=(const FreeIdentifier& /*other*/){}
	uint32 FindRegisteredGlobalCommandID(const T& control)
	{
		if (m_mapCommands.empty())
			return ERROR_ID;

		CommandMap::const_iterator itbegin = m_mapCommands.begin();
		CommandMap::const_iterator itend = m_mapCommands.end();
		for (; itbegin != itend; ++itbegin)
		{
			if (itbegin->second == control)
				return itbegin->first;
		}
		return ERROR_ID;
	}
	uint32 FindFreeCommandID() const
	{
		for (uint32 nID = m_firstid; nID <= m_lastid; nID++)
		{
			if (m_mapCommands.count(nID) == 0)
				return nID;
		}

		return ERROR_ID;
	}
	CommandMap& m_mapCommands;
	uint32 m_firstid;
	uint32 m_lastid;
};